Group 10

Libraries needed

Biological question and Project Scope

Clustering

kuang <- read.csv("./datasets/kuang-2014-microarray-expression.csv") ##local- needs to be changed 
time <- read.csv("./datasets/kuang-2014-microarry-expression-timepts.csv")
head(kuang[0:5])  ##preview data sets
tail(kuang[0:5]) 
rnaseq <- read.csv("./datasets/kuang-2014-rnaseq-expression.csv") #local needs to be changed
rnatime <- read.csv("./datasets/kuang-2014-rnaseq-expression-timepts.csv")
dim(kuang)
[1] 6241   37
# first remember the names
n <- kuang$Gene.name
# transpose all but the first column (Gene.name)
kuang_t <- as.data.frame(t(kuang[,-1]))
colnames(kuang_t) <- n
dim(kuang_t)
[1]   36 6241
dim(time)
[1] 36  1
kuang_t.time <- cbind(kuang_t, time = time$minute)
head(kuang_t.time[6241:6242])
colnames(kuang_t) %>% length()
[1] 6241
unique.genes <- colnames(kuang_t) %>% unique()
length(unique.genes)
[1] 6035

While looking at the data set we observed multiple genes that were present more than once. Using the unique function we can see that there are 6241 genes in the data set, but only 6035 unique genes. We are not sure for the reasoning behind this, our best guess is redundancy, but it is something to keep in mind.

Time plots

#visual of first 10 genes
first.10.genes <- c("YAL001C", "YAL002W", "YAL003W", "YAL004W", "YAL005C", "YAL007C", "YAL008W", "YAL009W", "YAL010C", "YAL011W")
ggplot(kuang_t.time, aes(x = time, y = YAL001C, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL001C")

ggplot(kuang_t.time, aes(x = time, y = YAL002W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL002W")

ggplot(kuang_t.time, aes(x = time, y = YAL003W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL003W")

ggplot(kuang_t.time, aes(x = time, y = YAL004W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL004W")

ggplot(kuang_t.time, aes(x = time, y = YAL005C, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL005C")

ggplot(kuang_t.time, aes(x = time, y = YAL007C, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL007C")

ggplot(kuang_t.time, aes(x = time, y = YAL008W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL008W")

ggplot(kuang_t.time, aes(x = time, y = YAL009W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL009W")

ggplot(kuang_t.time, aes(x = time, y = YAL010C, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL010C")

ggplot(kuang_t.time, aes(x = time, y = YAL011W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL011W")

Clustering

Complete method, with 1-Pearson correlation as the distance matrix

First, we attempted hierarchical clustering using the complete method with 1-Pearson’s correlation as the distance metric. The first thing we did was create the correlation matrix and then distance matrix of the transpose of the original data (with genes and the columns). We are clustered the transpose of the original matrix because we wanted to cluster genes based on their relative correlation over time. All of the clustering techniques we know cluster the columns, not rows, of the dataset.

## These take a lot of time so they are moved into their own code segment
kuang_t.cor <- kuang_t %>% cor(use="pairwise.complete.obs")  ##generate correlation measurements
kuang.dist <- as.dist(1 - kuang_t.cor)  ##use correlation to find distance measurements 
kuang.tree <- hclust(kuang.dist, method="complete")
kuang.dend <- as.dendrogram(kuang.tree) ## created & priviewed dendrogram object

To get an idea of the data we plotted the dendrogram. From the dendrogram it is clear that there are significant clusters in the dataset.

plot(kuang.dend, leaflab = "none")  ## removing labels 

To further get a feel for the dataset we plotted the dendrogram at several different cluster values (2, 4, and 8)- color coded to best analyze the data.

clusters_2 <- cutree(kuang.dend, k=2)
plot(color_branches(kuang.dend, k=2),leaflab="none")

table(clusters_2)
clusters_2
   1    2 
2956 3285 
clusters_4 <- cutree(kuang.dend, k=4)
plot(color_branches(kuang.dend, k=4),leaflab="none")

table(clusters_4)
clusters_4
   1    2    3    4 
2253  703 2313  972 
clusters_8 <- cutree(kuang.dend, k=8)
plot(color_branches(kuang.dend, k=8),leaflab="none")

table(clusters_8)
clusters_8
   1    2    3    4    5    6    7    8 
1535  703  404  718 1577  764  208  332 
sub.trees <- cut(kuang.dend, h = 1.75)  ##Height retrieved from 8 cluster Figure above
cluster1.final <- sub.trees$lower[[1]]
cluster2.final <- sub.trees$lower[[2]]
cluster3.final <- sub.trees$lower[[3]]
cluster4.final <- sub.trees$lower[[4]]
cluster5.final <- sub.trees$lower[[5]]
cluster6.final <- sub.trees$lower[[6]]
cluster7.final <- sub.trees$lower[[7]]
cluster8.final <- sub.trees$lower[[8]]
nleaves(cluster1.final)
[1] 703
nleaves(cluster2.final)
[1] 718
nleaves(cluster3.final)
[1] 1535
nleaves(cluster4.final)
[1] 764
nleaves(cluster5.final)
[1] 208
nleaves(cluster6.final)
[1] 332
nleaves(cluster7.final)
[1] 404
nleaves(cluster8.final)
[1] 1577

After reading our paper, we saw that they found three major clusters. We next did hierarchical clustering using k = 3 to see if our clusters align with the clusters found in the paper.

clusters_3 <- cutree(kuang.dend, k=3)
plot(color_branches(kuang.dend, k=3),leaflab="none", main = "Original Microarray dendrogram with k = 3")

table(clusters_3)
clusters_3
   1    2    3 
2956 2313  972 

We then cut the tree to extract these three clusters.

cut1 <- cut(kuang.dend, h = 1.9)
cut1$lower

Perfect. The first cluster countains 2956 genes, the second contains 972 genes, and the third contains 2313 genes.

To get a better idea we performed hierarchical clustering, starting with the first cluster on the left (pink)

plot(cut1$lower[[1]], leaflab="none", main = "Cluster 1 dendrogram")

We then tried plotting this at dendrogram at different k values to see what looks good.

plot(color_branches(cut1$lower[[1]], k=3), leaflab="none", main = "Cluster 1 dendrogram with k = 3")

The first two clusters (pink and green) looked pretty compact to us, so we did not explore them anymore. The third (blue) cluster appeared to have some significant subclusters in it, so we explored it more.

cluster1.cut1 <- cut(cut1$lower[[1]], h = 1.75)
cluster1.cut1$lower
[[1]]
'dendrogram' with 2 branches and 703 members total, at height 1.6383 

[[2]]
'dendrogram' with 2 branches and 718 members total, at height 1.708666 

[[3]]
'dendrogram' with 2 branches and 1535 members total, at height 1.7321 
plot(cluster1.cut1$lower[[3]], leaflab = "none")

We saw that there appeared to be 4 main clusters. Adding color allowed us to visualize if our observation held true.

plot(color_branches(cluster1.cut1$lower[[3]], k=4), leaflab="none", main = "Cluster 1 subtree dendrogram with k = 4")

That looked good to us. We then extracted these four clusters to see how large they were and what genes they contained.

cluster1.cut1.cutAgain <- cut(cluster1.cut1$lower[[3]], h = 1.4)
cluster1.cut1.cutAgain$lower
[[1]]
'dendrogram' with 2 branches and 312 members total, at height 1.361629 

[[2]]
'dendrogram' with 2 branches and 479 members total, at height 1.360901 

[[3]]
'dendrogram' with 2 branches and 342 members total, at height 1.138894 

[[4]]
'dendrogram' with 2 branches and 402 members total, at height 1.306937 

Next we looked at the smallest cluster ([[2]]).

plot(color_branches(cut1$lower[[2]], k=2), leaflab="none", main = "Cluster 2 dendrogram with k = 2")

Looking at this we saw there were two main clusters. We then cut this subtree again in order to extract these two subclusters.

cut1.cut2 <- cut(cut1$lower[[2]], h = 1.6)
cut1.cut2$lower
[[1]]
'dendrogram' with 2 branches and 764 members total, at height 1.413171 

[[2]]
'dendrogram' with 2 branches and 208 members total, at height 1.508391 

The smaller cluster (green) had 208 genes in it. This is a good size to work with, so we continued exploring this subcluster. First we plotted it.

plot(cut1.cut2$lower[[2]], leaflab = "none", main = "Subcluster of Cluster 2")

4 main clusters stuck out to us when looking at the above plot, so we plotted with color and k = 4.

plot(color_branches(cut1.cut2$lower[[2]], k=4), leaflab="none", main = "Subcluster of Cluster 2 dendrogram with k = 4")

We then extracted these four clusters.

cut1.cut2.cutTo4 <- cut(cut1.cut2$lower[[2]], h = 1.25)
cluster.genes <- as.character(labels(cut1.cut2.cutTo4$lower[[1]]))
cat(cluster.genes)
YOL146W YPL234C YDL097C YDR457W YDL224C YDR105C YFL020C YER152C YFR044C YKL135C YLL020C YLL020C YLL019C YLL020C YJL081C YJR017C YKL104C YAR019C YJL117W YBR016W YBR050C YDL159W YAR020C YCR038C YPL005W YPR091C YDR305C YDR366C YCR018C-A YLL061W YNL041C YNL140C YDR071C YPR188C YPR156C YCR097W-A YDR458C YOL109W YOL143C YOR122C YPL231W YLR447C YOL108C
kuang_t.cor.few <- kuang_t.cor[cluster.genes,cluster.genes]
f <- upper.tri(kuang_t.cor.few, diag=FALSE)
in.vector.form <- data.frame(vals = as.vector(kuang_t.cor.few[f]))
ggplot(in.vector.form, aes(x=vals)) + geom_histogram(bins=50)

The sizes looked reasonable to work with.

Lastly we analyzed the third ([[3]]) cluster (blue in the original dendrogram).

plot(cut1$lower[[3]], leaflab="none", main = "Cluster 3 dendrogram")

On this dendrogram we tried plotting it with different k values to see which made the most sense.

plot(color_branches(cut1$lower[[3]], k=5), leaflab="none", main = "Cluster 3 dendrogram with k = 5")

A k value of 5 looked good. As we have before, we then extracted these clusters by cutting the dendrogram.

cluster3.cut1 <- cut(cut1$lower[[3]], h = 1.6)
cluster3.cut1$lower
[[1]]
'dendrogram' with 2 branches and 332 members total, at height 1.565022 

[[2]]
'dendrogram' with 2 branches and 404 members total, at height 1.519815 

[[3]]
'dendrogram' with 2 branches and 141 members total, at height 1.563054 

[[4]]
'dendrogram' with 2 branches and 904 members total, at height 1.566672 

[[5]]
'dendrogram' with 2 branches and 532 members total, at height 1.5888 

RNAseq clustering

# first remember the names
nrna <- rnaseq$Gene.name
# transpose all but the first column (Gene.name)
rnaseq_t_zeros <- as.data.frame(t(rnaseq[,-1]))
colnames(rnaseq_t_zeros) <- nrna
#dim(rnaseq_t_zeros)
#dim(rnatime)
#tail(rnaseq_t_zeros[0:5])
rnaseq_t_zeros.time <- cbind(rnaseq_t_zeros, time = rnatime$hour)
#head(rnaseq_t_zeros.time[6241:6242])

Time plots for rnaseq

#visual of first 10 genes
first.10.genes <- c("YAL001C", "YAL002W", "YAL003W", "YAL004W", "YAL005C", "YAL007C", "YAL008W", "YAL009W", "YAL010C", "YAL011W")
ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL001C, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL001C")

ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL002W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL002W")

ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL003W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL003W")

ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL004W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL004W")

ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL005C, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL005C")

ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL007C, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL007C")

ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL008W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL008W")

ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL009W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL009W")

ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL010C, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL010C")

ggplot(rnaseq_t_zeros.time, aes(x = time, y = YAL011W, group = 1)) + geom_line() + labs(x = "Time (minutes)", y = "Expression of Gene", title = "YAL011W")

dim(rnaseq_t_zeros)
[1]   16 6241
head(rnaseq_t_zeros[,6240:6241])

Some of these genes have zero expression and need to be removed!

head(rnaseq_t_zeros[, colSums(rnaseq_t_zeros == 0) > 0])
rnaseq_t <- rnaseq_t_zeros[, colSums(rnaseq_t_zeros != 0) > 0]
head(rnaseq_t)
rnaseq.cor <- cor(rnaseq_t, use = "pairwise.complete.obs") 
rnaseq.dist <- as.dist(1-rnaseq.cor)
rnaseq.tree <- hclust(rnaseq.dist, method = "complete") 
rnaseq.dend <- as.dendrogram(rnaseq.tree)
plot(rnaseq.dend, leaflab = "none", main = "Original RNAdeq dendrogram")

Compared to the microarray dendrogram, it looked like these clusters are more compact and therefore stronger. We predicted this based off of the lower heights of most clusters. In order to see how true this was, we explored the clusters more.

plot(color_branches(rnaseq.dend, k=3),leaflab="none", main = "Original RNAseq dendrogram with k = 3")

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyBHcm91cCAxMAoKKkxpYnJhcmllcyBuZWVkZWQqIAoKCiMgQmlvbG9naWNhbCBxdWVzdGlvbiBhbmQgUHJvamVjdCBTY29wZQoKIyBDbHVzdGVyaW5nCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0KbGlicmFyeShkcGx5cik7CmxpYnJhcnkoInN0cmluZ3IiKTsKbGlicmFyeShnZ3Bsb3QyKTsKbGlicmFyeShkcGx5cik7CmxpYnJhcnkodGlkeXIpOwpsaWJyYXJ5KFJDb2xvckJyZXdlcik7CmxpYnJhcnkoZGVuZGV4dGVuZCk7CmxpYnJhcnkoZ3Bsb3RzKTsKbGlicmFyeShjbHVzdGVyKTsKYGBgCgpgYGB7cn0Ka3VhbmcgPC0gcmVhZC5jc3YoIi4vZGF0YXNldHMva3VhbmctMjAxNC1taWNyb2FycmF5LWV4cHJlc3Npb24uY3N2IikgIyNsb2NhbC0gbmVlZHMgdG8gYmUgY2hhbmdlZCAKdGltZSA8LSByZWFkLmNzdigiLi9kYXRhc2V0cy9rdWFuZy0yMDE0LW1pY3JvYXJyeS1leHByZXNzaW9uLXRpbWVwdHMuY3N2IikKCmhlYWQoa3VhbmdbMDo1XSkgICMjcHJldmlldyBkYXRhIHNldHMKdGFpbChrdWFuZ1swOjVdKSAKYGBgCgpgYGB7cn0Kcm5hc2VxIDwtIHJlYWQuY3N2KCIuL2RhdGFzZXRzL2t1YW5nLTIwMTQtcm5hc2VxLWV4cHJlc3Npb24uY3N2IikgI2xvY2FsIG5lZWRzIHRvIGJlIGNoYW5nZWQKcm5hdGltZSA8LSByZWFkLmNzdigiLi9kYXRhc2V0cy9rdWFuZy0yMDE0LXJuYXNlcS1leHByZXNzaW9uLXRpbWVwdHMuY3N2IikKYGBgCgpgYGB7cn0KZGltKGt1YW5nKQpgYGAKCmBgYHtyfQojIGZpcnN0IHJlbWVtYmVyIHRoZSBuYW1lcwpuIDwtIGt1YW5nJEdlbmUubmFtZQojIHRyYW5zcG9zZSBhbGwgYnV0IHRoZSBmaXJzdCBjb2x1bW4gKEdlbmUubmFtZSkKa3VhbmdfdCA8LSBhcy5kYXRhLmZyYW1lKHQoa3VhbmdbLC0xXSkpCmNvbG5hbWVzKGt1YW5nX3QpIDwtIG4KCmRpbShrdWFuZ190KQpkaW0odGltZSkKa3VhbmdfdC50aW1lIDwtIGNiaW5kKGt1YW5nX3QsIHRpbWUgPSB0aW1lJG1pbnV0ZSkKaGVhZChrdWFuZ190LnRpbWVbNjI0MTo2MjQyXSkKYGBgCgpgYGB7ciwgZWNobyA9IFRSVUV9CmNvbG5hbWVzKGt1YW5nX3QpICU+JSBsZW5ndGgoKQp1bmlxdWUuZ2VuZXMgPC0gY29sbmFtZXMoa3VhbmdfdCkgJT4lIHVuaXF1ZSgpCmxlbmd0aCh1bmlxdWUuZ2VuZXMpCgpgYGAKV2hpbGUgbG9va2luZyBhdCB0aGUgZGF0YSBzZXQgd2Ugb2JzZXJ2ZWQgbXVsdGlwbGUgZ2VuZXMgdGhhdCB3ZXJlIHByZXNlbnQgbW9yZSB0aGFuIG9uY2UuICBVc2luZyB0aGUgdW5pcXVlIGZ1bmN0aW9uIHdlIGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgNjI0MSBnZW5lcyBpbiB0aGUgZGF0YSBzZXQsIGJ1dCBvbmx5IDYwMzUgdW5pcXVlIGdlbmVzLiAgV2UgYXJlIG5vdCBzdXJlIGZvciB0aGUgcmVhc29uaW5nIGJlaGluZCB0aGlzLCBvdXIgYmVzdCBndWVzcyBpcyByZWR1bmRhbmN5LCBidXQgaXQgaXMgc29tZXRoaW5nIHRvIGtlZXAgaW4gbWluZC4KCiMjIFRpbWUgcGxvdHMgCgpgYGB7ciwgZWNobyA9IFRSVUUsIGZpZy5hbGlnbj0iY2VudGVyIn0KI3Zpc3VhbCBvZiBmaXJzdCAxMCBnZW5lcwpmaXJzdC4xMC5nZW5lcyA8LSBjKCJZQUwwMDFDIiwgIllBTDAwMlciLCAiWUFMMDAzVyIsICJZQUwwMDRXIiwgIllBTDAwNUMiLCAiWUFMMDA3QyIsICJZQUwwMDhXIiwgIllBTDAwOVciLCAiWUFMMDEwQyIsICJZQUwwMTFXIikKCmdncGxvdChrdWFuZ190LnRpbWUsIGFlcyh4ID0gdGltZSwgeSA9IFlBTDAwMUMsIGdyb3VwID0gMSkpICsgZ2VvbV9saW5lKCkgKyBsYWJzKHggPSAiVGltZSAobWludXRlcykiLCB5ID0gIkV4cHJlc3Npb24gb2YgR2VuZSIsIHRpdGxlID0gIllBTDAwMUMiKQoKZ2dwbG90KGt1YW5nX3QudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDAyVywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDAyVyIpCgpnZ3Bsb3Qoa3VhbmdfdC50aW1lLCBhZXMoeCA9IHRpbWUsIHkgPSBZQUwwMDNXLCBncm91cCA9IDEpKSArIGdlb21fbGluZSgpICsgbGFicyh4ID0gIlRpbWUgKG1pbnV0ZXMpIiwgeSA9ICJFeHByZXNzaW9uIG9mIEdlbmUiLCB0aXRsZSA9ICJZQUwwMDNXIikKCmdncGxvdChrdWFuZ190LnRpbWUsIGFlcyh4ID0gdGltZSwgeSA9IFlBTDAwNFcsIGdyb3VwID0gMSkpICsgZ2VvbV9saW5lKCkgKyBsYWJzKHggPSAiVGltZSAobWludXRlcykiLCB5ID0gIkV4cHJlc3Npb24gb2YgR2VuZSIsIHRpdGxlID0gIllBTDAwNFciKQoKZ2dwbG90KGt1YW5nX3QudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDA1QywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDA1QyIpCgpnZ3Bsb3Qoa3VhbmdfdC50aW1lLCBhZXMoeCA9IHRpbWUsIHkgPSBZQUwwMDdDLCBncm91cCA9IDEpKSArIGdlb21fbGluZSgpICsgbGFicyh4ID0gIlRpbWUgKG1pbnV0ZXMpIiwgeSA9ICJFeHByZXNzaW9uIG9mIEdlbmUiLCB0aXRsZSA9ICJZQUwwMDdDIikKCmdncGxvdChrdWFuZ190LnRpbWUsIGFlcyh4ID0gdGltZSwgeSA9IFlBTDAwOFcsIGdyb3VwID0gMSkpICsgZ2VvbV9saW5lKCkgKyBsYWJzKHggPSAiVGltZSAobWludXRlcykiLCB5ID0gIkV4cHJlc3Npb24gb2YgR2VuZSIsIHRpdGxlID0gIllBTDAwOFciKQoKZ2dwbG90KGt1YW5nX3QudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDA5VywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDA5VyIpCgpnZ3Bsb3Qoa3VhbmdfdC50aW1lLCBhZXMoeCA9IHRpbWUsIHkgPSBZQUwwMTBDLCBncm91cCA9IDEpKSArIGdlb21fbGluZSgpICsgbGFicyh4ID0gIlRpbWUgKG1pbnV0ZXMpIiwgeSA9ICJFeHByZXNzaW9uIG9mIEdlbmUiLCB0aXRsZSA9ICJZQUwwMTBDIikKCmdncGxvdChrdWFuZ190LnRpbWUsIGFlcyh4ID0gdGltZSwgeSA9IFlBTDAxMVcsIGdyb3VwID0gMSkpICsgZ2VvbV9saW5lKCkgKyBsYWJzKHggPSAiVGltZSAobWludXRlcykiLCB5ID0gIkV4cHJlc3Npb24gb2YgR2VuZSIsIHRpdGxlID0gIllBTDAxMVciKQpgYGAKCiMjIENsdXN0ZXJpbmcgCgoqKkNvbXBsZXRlIG1ldGhvZCwgd2l0aCAxLVBlYXJzb24gY29ycmVsYXRpb24gYXMgdGhlIGRpc3RhbmNlIG1hdHJpeCoqCiAKRmlyc3QsIHdlIGF0dGVtcHRlZCBoaWVyYXJjaGljYWwgY2x1c3RlcmluZyB1c2luZyB0aGUgY29tcGxldGUgbWV0aG9kIHdpdGggMS1QZWFyc29uJ3MgY29ycmVsYXRpb24gYXMgdGhlIGRpc3RhbmNlIG1ldHJpYy4gVGhlIGZpcnN0IHRoaW5nIHdlIGRpZCB3YXMgY3JlYXRlIHRoZSBjb3JyZWxhdGlvbiBtYXRyaXggYW5kIHRoZW4gZGlzdGFuY2UgbWF0cml4IG9mIHRoZSB0cmFuc3Bvc2Ugb2YgdGhlIG9yaWdpbmFsIGRhdGEgKHdpdGggZ2VuZXMgYW5kIHRoZSBjb2x1bW5zKS4gV2UgYXJlIGNsdXN0ZXJlZCB0aGUgdHJhbnNwb3NlIG9mIHRoZSBvcmlnaW5hbCBtYXRyaXggYmVjYXVzZSB3ZSB3YW50ZWQgdG8gY2x1c3RlciBnZW5lcyBiYXNlZCBvbiB0aGVpciByZWxhdGl2ZSBjb3JyZWxhdGlvbiBvdmVyIHRpbWUuIEFsbCBvZiB0aGUgY2x1c3RlcmluZyB0ZWNobmlxdWVzIHdlIGtub3cgY2x1c3RlciB0aGUgY29sdW1ucywgbm90IHJvd3MsIG9mIHRoZSBkYXRhc2V0LiAKCmBgYHtyfQojIyBUaGVzZSB0YWtlIGEgbG90IG9mIHRpbWUgc28gdGhleSBhcmUgbW92ZWQgaW50byB0aGVpciBvd24gY29kZSBzZWdtZW50Cmt1YW5nX3QuY29yIDwtIGt1YW5nX3QgJT4lIGNvcih1c2U9InBhaXJ3aXNlLmNvbXBsZXRlLm9icyIpICAjI2dlbmVyYXRlIGNvcnJlbGF0aW9uIG1lYXN1cmVtZW50cwprdWFuZy5kaXN0IDwtIGFzLmRpc3QoMSAtIGt1YW5nX3QuY29yKSAgIyN1c2UgY29ycmVsYXRpb24gdG8gZmluZCBkaXN0YW5jZSBtZWFzdXJlbWVudHMgCmBgYAoKYGBge3J9Cmt1YW5nLnRyZWUgPC0gaGNsdXN0KGt1YW5nLmRpc3QsIG1ldGhvZD0iY29tcGxldGUiKQprdWFuZy5kZW5kIDwtIGFzLmRlbmRyb2dyYW0oa3VhbmcudHJlZSkgIyMgY3JlYXRlZCAmIHByaXZpZXdlZCBkZW5kcm9ncmFtIG9iamVjdApgYGAKClRvIGdldCBhbiBpZGVhIG9mIHRoZSBkYXRhIHdlIHBsb3R0ZWQgdGhlIGRlbmRyb2dyYW0uICBGcm9tIHRoZSBkZW5kcm9ncmFtIGl0IGlzIGNsZWFyIHRoYXQgdGhlcmUgYXJlIHNpZ25pZmljYW50IGNsdXN0ZXJzIGluIHRoZSBkYXRhc2V0LiAKCmBgYHtyfQpwbG90KGt1YW5nLmRlbmQsIGxlYWZsYWIgPSAibm9uZSIpICAjIyByZW1vdmluZyBsYWJlbHMgCmBgYAoKVG8gZnVydGhlciBnZXQgYSBmZWVsIGZvciB0aGUgZGF0YXNldCB3ZSBwbG90dGVkIHRoZSBkZW5kcm9ncmFtIGF0IHNldmVyYWwgZGlmZmVyZW50IGNsdXN0ZXIgdmFsdWVzICgyLCA0LCBhbmQgOCktIGNvbG9yIGNvZGVkIHRvIGJlc3QgYW5hbHl6ZSB0aGUgZGF0YS4KCmBgYHtyfQpjbHVzdGVyc18yIDwtIGN1dHJlZShrdWFuZy5kZW5kLCBrPTIpCnBsb3QoY29sb3JfYnJhbmNoZXMoa3VhbmcuZGVuZCwgaz0yKSxsZWFmbGFiPSJub25lIikKdGFibGUoY2x1c3RlcnNfMikKYGBgCgpgYGB7cn0KY2x1c3RlcnNfNCA8LSBjdXRyZWUoa3VhbmcuZGVuZCwgaz00KQpwbG90KGNvbG9yX2JyYW5jaGVzKGt1YW5nLmRlbmQsIGs9NCksbGVhZmxhYj0ibm9uZSIpCnRhYmxlKGNsdXN0ZXJzXzQpCmBgYAoKYGBge3J9CmNsdXN0ZXJzXzggPC0gY3V0cmVlKGt1YW5nLmRlbmQsIGs9OCkKcGxvdChjb2xvcl9icmFuY2hlcyhrdWFuZy5kZW5kLCBrPTgpLGxlYWZsYWI9Im5vbmUiKQp0YWJsZShjbHVzdGVyc184KQpgYGAKCmBgYHtyfQpzdWIudHJlZXMgPC0gY3V0KGt1YW5nLmRlbmQsIGggPSAxLjc1KSAgIyNIZWlnaHQgcmV0cmlldmVkIGZyb20gOCBjbHVzdGVyIEZpZ3VyZSBhYm92ZQpjbHVzdGVyMS5maW5hbCA8LSBzdWIudHJlZXMkbG93ZXJbWzFdXQpjbHVzdGVyMi5maW5hbCA8LSBzdWIudHJlZXMkbG93ZXJbWzJdXQpjbHVzdGVyMy5maW5hbCA8LSBzdWIudHJlZXMkbG93ZXJbWzNdXQpjbHVzdGVyNC5maW5hbCA8LSBzdWIudHJlZXMkbG93ZXJbWzRdXQpjbHVzdGVyNS5maW5hbCA8LSBzdWIudHJlZXMkbG93ZXJbWzVdXQpjbHVzdGVyNi5maW5hbCA8LSBzdWIudHJlZXMkbG93ZXJbWzZdXQpjbHVzdGVyNy5maW5hbCA8LSBzdWIudHJlZXMkbG93ZXJbWzddXQpjbHVzdGVyOC5maW5hbCA8LSBzdWIudHJlZXMkbG93ZXJbWzhdXQpubGVhdmVzKGNsdXN0ZXIxLmZpbmFsKQpubGVhdmVzKGNsdXN0ZXIyLmZpbmFsKQpubGVhdmVzKGNsdXN0ZXIzLmZpbmFsKQpubGVhdmVzKGNsdXN0ZXI0LmZpbmFsKQpubGVhdmVzKGNsdXN0ZXI1LmZpbmFsKQpubGVhdmVzKGNsdXN0ZXI2LmZpbmFsKQpubGVhdmVzKGNsdXN0ZXI3LmZpbmFsKQpubGVhdmVzKGNsdXN0ZXI4LmZpbmFsKQpgYGAKCgpBZnRlciByZWFkaW5nIG91ciBwYXBlciwgd2Ugc2F3IHRoYXQgdGhleSBmb3VuZCB0aHJlZSBtYWpvciBjbHVzdGVycy4gIFdlIG5leHQgZGlkIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nIHVzaW5nIGsgPSAzIHRvIHNlZSBpZiBvdXIgY2x1c3RlcnMgYWxpZ24gd2l0aCB0aGUgY2x1c3RlcnMgZm91bmQgaW4gdGhlIHBhcGVyLgoKYGBge3J9CmNsdXN0ZXJzXzMgPC0gY3V0cmVlKGt1YW5nLmRlbmQsIGs9MykKcGxvdChjb2xvcl9icmFuY2hlcyhrdWFuZy5kZW5kLCBrPTMpLGxlYWZsYWI9Im5vbmUiLCBtYWluID0gIk9yaWdpbmFsIE1pY3JvYXJyYXkgZGVuZHJvZ3JhbSB3aXRoIGsgPSAzIikKdGFibGUoY2x1c3RlcnNfMykKYGBgCldlIHRoZW4gY3V0IHRoZSB0cmVlIHRvIGV4dHJhY3QgdGhlc2UgdGhyZWUgY2x1c3RlcnMuCmBgYHtyfQpjdXQxIDwtIGN1dChrdWFuZy5kZW5kLCBoID0gMS45KQpjdXQxJGxvd2VyCmBgYAoKClBlcmZlY3QuICBUaGUgZmlyc3QgY2x1c3RlciBjb3VudGFpbnMgMjk1NiBnZW5lcywgdGhlIHNlY29uZCBjb250YWlucyA5NzIgZ2VuZXMsIGFuZCB0aGUgdGhpcmQgY29udGFpbnMgMjMxMyBnZW5lcy4KClRvIGdldCBhIGJldHRlciBpZGVhIHdlIHBlcmZvcm1lZCBoaWVyYXJjaGljYWwgY2x1c3RlcmluZywgc3RhcnRpbmcgd2l0aCB0aGUgZmlyc3QgY2x1c3RlciBvbiB0aGUgbGVmdCAocGluaykKYGBge3J9CnBsb3QoY3V0MSRsb3dlcltbMV1dLCBsZWFmbGFiPSJub25lIiwgbWFpbiA9ICJDbHVzdGVyIDEgZGVuZHJvZ3JhbSIpCmBgYApXZSB0aGVuIHRyaWVkIHBsb3R0aW5nIHRoaXMgYXQgZGVuZHJvZ3JhbSBhdCBkaWZmZXJlbnQgayB2YWx1ZXMgdG8gc2VlIHdoYXQgbG9va3MgZ29vZC4KYGBge3J9CnBsb3QoY29sb3JfYnJhbmNoZXMoY3V0MSRsb3dlcltbMV1dLCBrPTMpLCBsZWFmbGFiPSJub25lIiwgbWFpbiA9ICJDbHVzdGVyIDEgZGVuZHJvZ3JhbSB3aXRoIGsgPSAzIikKYGBgClRoZSBmaXJzdCB0d28gY2x1c3RlcnMgKHBpbmsgYW5kIGdyZWVuKSBsb29rZWQgcHJldHR5IGNvbXBhY3QgdG8gdXMsIHNvIHdlIGRpZCBub3QgZXhwbG9yZSB0aGVtIGFueW1vcmUuICBUaGUgdGhpcmQgKGJsdWUpIGNsdXN0ZXIgYXBwZWFyZWQgdG8gaGF2ZSBzb21lIHNpZ25pZmljYW50IHN1YmNsdXN0ZXJzIGluIGl0LCBzbyB3ZSBleHBsb3JlZCBpdCBtb3JlLgoKYGBge3J9CmNsdXN0ZXIxLmN1dDEgPC0gY3V0KGN1dDEkbG93ZXJbWzFdXSwgaCA9IDEuNzUpCmNsdXN0ZXIxLmN1dDEkbG93ZXIKcGxvdChjbHVzdGVyMS5jdXQxJGxvd2VyW1szXV0sIGxlYWZsYWIgPSAibm9uZSIpCmBgYAoKV2Ugc2F3IHRoYXQgdGhlcmUgYXBwZWFyZWQgdG8gYmUgNCBtYWluIGNsdXN0ZXJzLiAgQWRkaW5nIGNvbG9yIGFsbG93ZWQgdXMgdG8gdmlzdWFsaXplIGlmIG91ciBvYnNlcnZhdGlvbiBoZWxkIHRydWUuCmBgYHtyfQpwbG90KGNvbG9yX2JyYW5jaGVzKGNsdXN0ZXIxLmN1dDEkbG93ZXJbWzNdXSwgaz00KSwgbGVhZmxhYj0ibm9uZSIsIG1haW4gPSAiQ2x1c3RlciAxIHN1YnRyZWUgZGVuZHJvZ3JhbSB3aXRoIGsgPSA0IikKYGBgClRoYXQgbG9va2VkIGdvb2QgdG8gdXMuICBXZSB0aGVuIGV4dHJhY3RlZCB0aGVzZSBmb3VyIGNsdXN0ZXJzIHRvIHNlZSBob3cgbGFyZ2UgdGhleSB3ZXJlIGFuZCB3aGF0IGdlbmVzIHRoZXkgY29udGFpbmVkLgpgYGB7cn0KY2x1c3RlcjEuY3V0MS5jdXRBZ2FpbiA8LSBjdXQoY2x1c3RlcjEuY3V0MSRsb3dlcltbM11dLCBoID0gMS40KQpjbHVzdGVyMS5jdXQxLmN1dEFnYWluJGxvd2VyCmBgYAoKCk5leHQgd2UgbG9va2VkIGF0IHRoZSBzbWFsbGVzdCBjbHVzdGVyIChbWzJdXSkuICAKYGBge3J9CnBsb3QoY29sb3JfYnJhbmNoZXMoY3V0MSRsb3dlcltbMl1dLCBrPTIpLCBsZWFmbGFiPSJub25lIiwgbWFpbiA9ICJDbHVzdGVyIDIgZGVuZHJvZ3JhbSB3aXRoIGsgPSAyIikKYGBgCkxvb2tpbmcgYXQgdGhpcyB3ZSBzYXcgdGhlcmUgd2VyZSB0d28gbWFpbiBjbHVzdGVycy4gIFdlIHRoZW4gY3V0IHRoaXMgc3VidHJlZSBhZ2FpbiBpbiBvcmRlciB0byBleHRyYWN0IHRoZXNlIHR3byBzdWJjbHVzdGVycy4KYGBge3J9CmN1dDEuY3V0MiA8LSBjdXQoY3V0MSRsb3dlcltbMl1dLCBoID0gMS42KQpjdXQxLmN1dDIkbG93ZXIKYGBgClRoZSBzbWFsbGVyIGNsdXN0ZXIgKGdyZWVuKSBoYWQgMjA4IGdlbmVzIGluIGl0LiAgVGhpcyBpcyBhIGdvb2Qgc2l6ZSB0byB3b3JrIHdpdGgsIHNvIHdlIGNvbnRpbnVlZCBleHBsb3JpbmcgdGhpcyBzdWJjbHVzdGVyLiAgRmlyc3Qgd2UgcGxvdHRlZCBpdC4KYGBge3J9CnBsb3QoY3V0MS5jdXQyJGxvd2VyW1syXV0sIGxlYWZsYWIgPSAibm9uZSIsIG1haW4gPSAiU3ViY2x1c3RlciBvZiBDbHVzdGVyIDIiKQpgYGAKNCBtYWluIGNsdXN0ZXJzIHN0dWNrIG91dCB0byB1cyB3aGVuIGxvb2tpbmcgYXQgdGhlIGFib3ZlIHBsb3QsIHNvIHdlIHBsb3R0ZWQgd2l0aCBjb2xvciBhbmQgayA9IDQuCmBgYHtyfQpwbG90KGNvbG9yX2JyYW5jaGVzKGN1dDEuY3V0MiRsb3dlcltbMl1dLCBrPTQpLCBsZWFmbGFiPSJub25lIiwgbWFpbiA9ICJTdWJjbHVzdGVyIG9mIENsdXN0ZXIgMiBkZW5kcm9ncmFtIHdpdGggayA9IDQiKQpgYGAKV2UgdGhlbiBleHRyYWN0ZWQgdGhlc2UgZm91ciBjbHVzdGVycy4KYGBge3J9CmN1dDEuY3V0Mi5jdXRUbzQgPC0gY3V0KGN1dDEuY3V0MiRsb3dlcltbMl1dLCBoID0gMS4yNSkKY2x1c3Rlci5nZW5lcyA8LSBhcy5jaGFyYWN0ZXIobGFiZWxzKGN1dDEuY3V0Mi5jdXRUbzQkbG93ZXJbWzFdXSkpCmNhdChjbHVzdGVyLmdlbmVzKQprdWFuZ190LmNvci5mZXcgPC0ga3VhbmdfdC5jb3JbY2x1c3Rlci5nZW5lcyxjbHVzdGVyLmdlbmVzXQpmIDwtIHVwcGVyLnRyaShrdWFuZ190LmNvci5mZXcsIGRpYWc9RkFMU0UpCmluLnZlY3Rvci5mb3JtIDwtIGRhdGEuZnJhbWUodmFscyA9IGFzLnZlY3RvcihrdWFuZ190LmNvci5mZXdbZl0pKQpnZ3Bsb3QoaW4udmVjdG9yLmZvcm0sIGFlcyh4PXZhbHMpKSArIGdlb21faGlzdG9ncmFtKGJpbnM9NTApCmBgYApUaGUgc2l6ZXMgbG9va2VkIHJlYXNvbmFibGUgdG8gd29yayB3aXRoLiAgCgpMYXN0bHkgd2UgYW5hbHl6ZWQgdGhlIHRoaXJkIChbWzNdXSkgY2x1c3RlciAoYmx1ZSBpbiB0aGUgb3JpZ2luYWwgZGVuZHJvZ3JhbSkuCgpgYGB7cn0KcGxvdChjdXQxJGxvd2VyW1szXV0sIGxlYWZsYWI9Im5vbmUiLCBtYWluID0gIkNsdXN0ZXIgMyBkZW5kcm9ncmFtIikKYGBgCk9uIHRoaXMgZGVuZHJvZ3JhbSB3ZSB0cmllZCBwbG90dGluZyBpdCB3aXRoIGRpZmZlcmVudCBrIHZhbHVlcyB0byBzZWUgd2hpY2ggbWFkZSB0aGUgbW9zdCBzZW5zZS4KYGBge3J9CnBsb3QoY29sb3JfYnJhbmNoZXMoY3V0MSRsb3dlcltbM11dLCBrPTUpLCBsZWFmbGFiPSJub25lIiwgbWFpbiA9ICJDbHVzdGVyIDMgZGVuZHJvZ3JhbSB3aXRoIGsgPSA1IikKYGBgCkEgayB2YWx1ZSBvZiA1IGxvb2tlZCBnb29kLiAgQXMgd2UgaGF2ZSBiZWZvcmUsIHdlIHRoZW4gZXh0cmFjdGVkIHRoZXNlIGNsdXN0ZXJzIGJ5IGN1dHRpbmcgdGhlIGRlbmRyb2dyYW0uCmBgYHtyfQpjbHVzdGVyMy5jdXQxIDwtIGN1dChjdXQxJGxvd2VyW1szXV0sIGggPSAxLjYpCmNsdXN0ZXIzLmN1dDEkbG93ZXIKYGBgCgojI1JOQXNlcSBjbHVzdGVyaW5nCgpgYGB7cn0KIyBmaXJzdCByZW1lbWJlciB0aGUgbmFtZXMKbnJuYSA8LSBybmFzZXEkR2VuZS5uYW1lCgojIHRyYW5zcG9zZSBhbGwgYnV0IHRoZSBmaXJzdCBjb2x1bW4gKEdlbmUubmFtZSkKcm5hc2VxX3RfemVyb3MgPC0gYXMuZGF0YS5mcmFtZSh0KHJuYXNlcVssLTFdKSkKY29sbmFtZXMocm5hc2VxX3RfemVyb3MpIDwtIG5ybmEKCiNkaW0ocm5hc2VxX3RfemVyb3MpCiNkaW0ocm5hdGltZSkKI3RhaWwocm5hc2VxX3RfemVyb3NbMDo1XSkKcm5hc2VxX3RfemVyb3MudGltZSA8LSBjYmluZChybmFzZXFfdF96ZXJvcywgdGltZSA9IHJuYXRpbWUkaG91cikKI2hlYWQocm5hc2VxX3RfemVyb3MudGltZVs2MjQxOjYyNDJdKQpgYGAKCiMjIFRpbWUgcGxvdHMgZm9yIHJuYXNlcQoKYGBge3IsIGVjaG8gPSBUUlVFLCBmaWcuYWxpZ249ImNlbnRlciJ9CiN2aXN1YWwgb2YgZmlyc3QgMTAgZ2VuZXMKZmlyc3QuMTAuZ2VuZXMgPC0gYygiWUFMMDAxQyIsICJZQUwwMDJXIiwgIllBTDAwM1ciLCAiWUFMMDA0VyIsICJZQUwwMDVDIiwgIllBTDAwN0MiLCAiWUFMMDA4VyIsICJZQUwwMDlXIiwgIllBTDAxMEMiLCAiWUFMMDExVyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDAxQywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDAxQyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDAyVywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDAyVyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDAzVywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDAzVyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDA0VywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDA0VyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDA1QywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDA1QyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDA3QywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDA3QyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDA4VywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDA4VyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDA5VywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDA5VyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDEwQywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDEwQyIpCgpnZ3Bsb3Qocm5hc2VxX3RfemVyb3MudGltZSwgYWVzKHggPSB0aW1lLCB5ID0gWUFMMDExVywgZ3JvdXAgPSAxKSkgKyBnZW9tX2xpbmUoKSArIGxhYnMoeCA9ICJUaW1lIChtaW51dGVzKSIsIHkgPSAiRXhwcmVzc2lvbiBvZiBHZW5lIiwgdGl0bGUgPSAiWUFMMDExVyIpCmBgYAoKYGBge3J9CmRpbShybmFzZXFfdF96ZXJvcykKaGVhZChybmFzZXFfdF96ZXJvc1ssNjI0MDo2MjQxXSkKYGBgCgpTb21lIG9mIHRoZXNlIGdlbmVzIGhhdmUgemVybyBleHByZXNzaW9uIGFuZCBuZWVkIHRvIGJlIHJlbW92ZWQhCgpgYGB7cn0KaGVhZChybmFzZXFfdF96ZXJvc1ssIGNvbFN1bXMocm5hc2VxX3RfemVyb3MgPT0gMCkgPiAwXSkKYGBgCgpgYGB7cn0Kcm5hc2VxX3QgPC0gcm5hc2VxX3RfemVyb3NbLCBjb2xTdW1zKHJuYXNlcV90X3plcm9zICE9IDApID4gMF0KaGVhZChybmFzZXFfdCkKYGBgCgpgYGB7cn0Kcm5hc2VxLmNvciA8LSBjb3Iocm5hc2VxX3QsIHVzZSA9ICJwYWlyd2lzZS5jb21wbGV0ZS5vYnMiKSAKcm5hc2VxLmRpc3QgPC0gYXMuZGlzdCgxLXJuYXNlcS5jb3IpCmBgYAoKYGBge3J9CnJuYXNlcS50cmVlIDwtIGhjbHVzdChybmFzZXEuZGlzdCwgbWV0aG9kID0gImNvbXBsZXRlIikgCnJuYXNlcS5kZW5kIDwtIGFzLmRlbmRyb2dyYW0ocm5hc2VxLnRyZWUpCmBgYAoKYGBge3J9CnBsb3Qocm5hc2VxLmRlbmQsIGxlYWZsYWIgPSAibm9uZSIsIG1haW4gPSAiT3JpZ2luYWwgUk5BZGVxIGRlbmRyb2dyYW0iKQpgYGAKQ29tcGFyZWQgdG8gdGhlIG1pY3JvYXJyYXkgZGVuZHJvZ3JhbSwgaXQgbG9va2VkIGxpa2UgdGhlc2UgY2x1c3RlcnMgYXJlIG1vcmUgY29tcGFjdCBhbmQgdGhlcmVmb3JlIHN0cm9uZ2VyLiAgV2UgcHJlZGljdGVkIHRoaXMgYmFzZWQgb2ZmIG9mIHRoZSBsb3dlciBoZWlnaHRzIG9mIG1vc3QgY2x1c3RlcnMuICBJbiBvcmRlciB0byBzZWUgaG93IHRydWUgdGhpcyB3YXMsIHdlIGV4cGxvcmVkIHRoZSBjbHVzdGVycyBtb3JlLgpgYGB7cn0KcGxvdChjb2xvcl9icmFuY2hlcyhybmFzZXEuZGVuZCwgaz0zKSxsZWFmbGFiPSJub25lIiwgbWFpbiA9ICJPcmlnaW5hbCBSTkFzZXEgZGVuZHJvZ3JhbSB3aXRoIGsgPSAzIikKYGBgCgo=